package com.timk.goserver.client.ui.screens;

import java.util.List;

import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.timk.goserver.client.model.ClientUserInfo;
import com.timk.goserver.client.services.NoSessionException;
import com.timk.goserver.client.ui.widgets.CenteredDialog;
import com.timk.goserver.client.ui.widgets.FocusCommand;
import com.timk.goserver.client.ui.widgets.RankGraphLink;
import com.timk.goserver.client.ui.widgets.StatusLabel;
import com.timk.goserver.client.ui.widgets.UserLink;
import com.timk.goserver.client.ui.widgets.UserLinkListener;

/**
 * Dialog for listing users
 * @author TKington
 *
 */
public class UserListDialog extends CenteredDialog {
	private static final int RESULTS_PER_PAGE = 20;
	
	private final UserLinkListener listener;
	private final TextBox searchText;
	private final Button searchButton;
	private final Button prevPageButton;
	private final Button nextPageButton;
	final StatusLabel status; // NOPMD - Explicit scoping
	private final FlexTable table;
	int startIndex = 0; // NOPMD - Explicit scoping
	
	/**
	 * Creates a UserListDialog
	 * @param listener UserLinkListener that handles the click event
	 */
	public UserListDialog(UserLinkListener listener) {
		super(null);
		this.listener = listener;
		
		setText("Users");
		
		VerticalPanel panel = new VerticalPanel();
		panel.setWidth("100%");
		
		HorizontalPanel searchPanel = new HorizontalPanel();
		searchPanel.setWidth("100%");
		
		searchPanel.add(new Label("Search String:"));
		
		searchText = new TextBox();
		searchPanel.add(searchText);
		
		searchButton = new Button("Search");
		searchButton.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				startIndex = 0;
				refreshUsers();
			}
		});
		searchPanel.add(searchButton);

		panel.add(searchPanel);

		status = new StatusLabel();
		panel.add(status);
		
		table = new FlexTable();
		table.addStyleName("goserver-Table");
		panel.add(table);
		
		HorizontalPanel buttonPanel = new HorizontalPanel();
		
		prevPageButton = new Button("&lt;");
		prevPageButton.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				prevPage();
			}
		});
		buttonPanel.add(prevPageButton);
		
		nextPageButton = new Button("&gt;");
		nextPageButton.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				nextPage();
			}
		});
		buttonPanel.add(nextPageButton);
		
		Button closeButton = new Button("Close");
		closeButton.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				hide();
			}
		});
		buttonPanel.add(closeButton);
		
		panel.add(buttonPanel);
		
		setWidget(panel);
		
		DeferredCommand.add(new FocusCommand(searchText));
		
		refreshUsers();
	}
	
	void prevPage() {
		startIndex -= RESULTS_PER_PAGE;
		if(startIndex < 0) {
			startIndex = 0;
		}
		
		refreshUsers();
	}
	
	void nextPage() {
		startIndex += RESULTS_PER_PAGE;
		
		refreshUsers();
	}
	
	final void refreshUsers() {
		enableButtons(false);
		
		MainPanel.userService.getUsers(startIndex, RESULTS_PER_PAGE, 
				searchText.getText(), new AsyncCallback() {
			public void onSuccess(Object result) {
				enableButtons(true);
				status.clear();
				fillTable((List)result);
			}
			
			public void onFailure(Throwable caught) {
				if(caught instanceof NoSessionException) {
					MainPanel.sessionExpired(caught.getMessage());
					return;
				}
				
				enableButtons(true);
				status.setError("Failed to get users: " + caught.getMessage());
			}
		});
	}
	
	final void fillTable(List users) {
		int rowsToDelete = table.getRowCount();
		for(int i = 0; i < rowsToDelete; i++) {
			table.removeRow(0);
		}
		
		if(users.isEmpty()) {
			table.setVisible(false);
			status.setInfo("No users found");
			return;
		}
		
		table.setVisible(true);
		table.setHTML(0, 0, "<b>UserId</b>");
		table.setHTML(0, 1, "<b>Name</b>");
		table.setHTML(0, 2, "<b>Rank</b>");
		
		int curRow = 1;
		for(int i = 0; i < users.size(); i++) {
			ClientUserInfo user = (ClientUserInfo)users.get(i);

			UserLink link = new UserLink(this, user.getUsername(), listener);
			table.setWidget(curRow, 0, link);
			
			table.setText(curRow, 1, user.getFullname());
			
			RankGraphLink graphLink = new RankGraphLink(user.getUsername());
			graphLink.setHTML("<u>" + user.getRank() + "</u>");
			table.setWidget(curRow, 2, graphLink);
			
			curRow++;
		}
		
		enableButtons();
		centerPopup();
	}
	
	final void enableButtons(boolean enabled) {
		searchButton.setEnabled(enabled);
		
		//	Don't re-enable the page buttons without a good reason
		if(!enabled) {
			prevPageButton.setEnabled(enabled);
			nextPageButton.setEnabled(enabled);
		}
	}
	
	private void enableButtons() {
		nextPageButton.setEnabled(table.getRowCount() > RESULTS_PER_PAGE);
		prevPageButton.setEnabled(startIndex > 0);
	}
}
